Technical Note TN2102
The System Sound APIs for Mac OS X 10.2, 10.3 and later

このテクニカルノートでは、 Mac OS X 10.2、10.3 以降、SystemSound.h で利用できる警告音とユーザインタフェースのサウンドエフェクトを正しく再生するための System Sound API について説明します。





はじめに

Mac OS X では、警告音とサウンドエフェクト用に優先的に使用するオーディオデバイス(Default System Output Device)と、システムによって生成されるその他のオーディオ用のサウンド出力デバイス(Default Output Device)をユーザが各自で選択できます。同じデバイス(内蔵スピーカーなど)を設定することも、まったく異なる 2 つのデバイスを設定することもできます。

System Sound API を使って、デベロッパは、警告音に関するすべてのシステム設定に従いながら、すべての属性を使って警告音を正しく再生することができます。たとえば、オーディオ出力を利用できない場合や、「消音」または「ユニバーサルアクセス」システム環境設定の「音声」の「警告音が鳴るときに画面を点滅させる」など、ユーザ指定の環境設定がなされているときに画面を点滅させる機能があります。

また、「サウンド」システム環境設定を使って、「ユーザインタフェースのサウンドエフェクトを再生する」チェックボックスをチェックすると、「ユーザインタフェースのサウンドエフェクト」を正しく再生することができます(図 1 を参照)。

どちらの場合も、オーディオの出力先は、警告とサウンドエフェクト用に選択した Default System Output Device になります。

図 1 では警告音とサウンドエフェクト用の Default System Output デバイス(「警告とサウンドエフェクトの再生装置」ポップアップメニューから選択)が「内蔵スピーカー」に設定され、図 2 では Default Output Device は「EDIROL UA-3D USB」デバイスに設定されています。

一般的なユーザ設定では、iTunes で購入したミュージックは USB スピーカー(Default Output Device)で再生し、警告とサウンドエフェクトは内蔵スピーカー(Default System Output Device)で再生します。System Sound API を使用すると、アプリケーションが警告とサウンドエフェクトを間違ったデバイス(たとえば、SpinalTap のグレイティストヒットを大音量で演奏するようにボリュームを上げたスピーカー)で再生しないように保証されます。

注意: 警告音を使用するアプリケーションであれば、NSSound や QuickTime などの大掛かりな方法ではなく、System Sound API を使うのが適したアプローチです。

警告とサウンドエフェクト

図 1. 警告とサウンドエフェクト

サウンド出力

図 2. サウンド出力

先頭に戻る

System Sound API

以下の API は、"SystemSound.h" に定義されています。"SystemSound.h" は、CoreServices 包括フレームワークに属する OSServices フレームワークの一部です。

先頭に戻る

警告音

(Mac OS X 10.2 以降で利用可能)

警告音を再生するには 2 つの API があります。

AlertSoundPlay (Mac OS X 10.2 以降で利用可能) は、従来の Mac OS の SysBeep と同じで、これに取って代わるものです。これはパラメータを取らず、現在選択されている警告音を Default System Output Device から再生します(図 1 を参照)。この呼び出しは、先に再生している警告音を妨害します。

void AlertSoundPlay(void);

AlertSoundPlayCustomSound (Mac OS X 10.3 以降で利用可能) は SystemSoundActionID を受け取り、この actionID で指定された警告音を AlertSoundPlay と同じ動作で再生します。

void AlertSoundPlayCustomSound(SystemSoundActionID inAction)

inAction: AlertSound の動作で再生するサウンドを示す SystemSoundActionID。

先頭に戻る

ユーザインタフェースのサウンドエフェクト

(Mac OS X 10.3 以降で利用可能)

ユーザインタフェースのサウンドエフェクトを再生する API は 1 つです。

SystemSoundPlaySystemSoundActionID を受け取り、この actionID で指定されたサウンドを、選択されている Default System Output Device からすぐに再生します(図 1 を参照)。この呼び出しは、再生中に継続や変更を必要としない、1 回だけのユーザインタフェースアクションに使用します。サウンドの継続ループは無視されます。

警告: SystemSoundPlay は、実際には Mac OS X 10.2 でエクスポートされており、SystemSound.h もこれを Mac OS X 10.2 で利用可能だと言っています。

技術的に正しいですが、SystemSoundPlay を Mac OS X 10.2.x で呼び出すと直ちにクラッシュします。この動作は少し面白いかもしれませんが、あまり有用ではありません(同意していただけると思います)。そのため、テクニカルノートでは、SystemSoundPlay を利用できるのは Mac OS X 10.3 以降であるとしています。

void SystemSoundPlay(SystemSoundActionID inAction)

inAction: 再生するシステムサウンドを示す SystemSoundActionID。

先頭に戻る

SystemSoundActionID の作成

(Mac OS X 10.2 以降で利用可能)

SystemSoundActionID を扱うには 2 つの API があります。

SystemSoundGetActionID を使うと、オーディオファイルを提供することによって、カスタムのサウンド SystemSoundActionID を作成できます。この呼び出しを使って、System Sound Server にサウンドを追加し、SystemSoundPlay または AlertSoundPlayCustomSound を介して再生できます。この呼び出しは、オーディオファイルを指定する FSRef * を受け取り、成功した場合は SystemSoundActionID を返します。

OSStatus SystemSoundGetActionID(
  const FSRef * userFile,
  SystemSoundActionID * outAction)

userFile: システムサウンドとして使用するオーディオファイルに対応する const FSRef * 。
          AudioToolbox フレームワークの AudioFile API でサポートされている
          任意のオーディオファイル。

outAction: 成功すると、SystemSoundActionID が返される。
           これを SystemSoundPlay() または AlertSoundPlayCustomSound() に渡す。

SystemSoundRemoveActionID により、「カスタム」サウンドを削除できます。 この呼び出しは、SystemSoundGetActionID で作成した「カスタム」サウンドが不要になった場合に使用します。不要になったリソースを System Sound Server が解放できるように、忘れずにこの関数を呼び出す必要があります。この関数は、SystemSoundActionID パラメータを取ります。

OSStatus SystemSoundRemoveActionID(SystemSoundActionID inAction)

inAction: 削除するシステムサウンドを示す SystemSoundActionID。

先頭に戻る

完了ルーチン

(Mac OS X 10.3 以降で利用可能)

完了ルーチンを扱う API は 2 つあります。

SystemSoundSetCompletionRoutine を使うと、特定の SystemSoundActionID に対応する完了ルーチンを設定できます。System Sound Server が指定された「カスタム」サウンドの再生を終えると、この完了ルーチンが呼び出されます。

OSStatus SystemSoundSetCompletionRoutine(
  SystemSoundActionID inAction,
  CFRunLoopRef inRunLoop,
  CFStringRef inRunLoopMode,
  SystemSoundCompletionUPP inCompletionRoutine,
  void * inUserData

inAction: 完了ルーチンが関連付けられる SystemSoundActionID。

inRunLoop: 完了ルーチンの対象となる実行ループを示す CFRunLoopRef indicating。
           メインループの場合は NULL を渡す。

inRunLoopMode: 完了ルーチンが実行される、実行ループの実行ループモードを
               示す CFStringRef。
               kCFRunLoopDefaultMode を使用するには NULL を渡す。

inCompletionRoutine: 指定された SystemSoundActionID がサーバでの再生を完了したときに
                     呼び出される完了ルーチンを示す SystemSoundCompletionProc。

inUserData: ユーザデータを完了ルーチンに渡すための void * 。

SystemSoundRemoveCompletionRoutine は、特定の SystemSoundActionID に対応する完了ルーチンを削除します。サウンドの再生を終えたときに、対応する「カスタム」サウンドの完了ルーチンセットを呼び出したくない場合に、この関数を呼び出します。

void SystemSoundRemoveCompletionRoutine(SystemSoundActionID inAction)

inAction: 完了ルーチンが現在関連付けられている SystemSoundActionID。

先頭に戻る

使用例

リスト 1. カスタム警告音の再生

SystemSoundActionID gFunkSoundID = 0;

OSStatus CreateFunkActionID(void)
{
  const char *soundFilePath = "/System/Library/Sounds/Funk.aiff";
  FSRef soundFileRef;
  OSStatus err;

  err = FSPathMakeRef(soundFilePath, &soundFileRef, NULL);
  if (noErr == err) {
    err = SystemSoundGetActionID(&soundFileRef, &gFunkSoundID);
  }

  return err;
}

void MyDoSomethingFunction(void)
{
  .
  .
  .
  if (badBadThing)
    AlertSoundPlayCustomSound(gFunkSoundID);
    // 注記:この呼び出しの直後に Action ID を削除しないように
    // 注意すること。システムに対して、実際にサウンドを再生する機会を
    // 与える必要がある。
  .
  .
  .
}

void MyCleanUpActionID(void)
{
    // 処理を完了したら
    // ActionID の SystemSoundRemoveActionID を呼び出す。
    // 注記:上の注記でも示したように、システムにサウンドを再生する機会を与える前に
    // Action ID を削除してしまわないようにする。

  SystemSoundRemoveActionID(gFunkSoundID);
}

先頭に戻る

ドキュメントの改訂履歴

日付メモ
2004-07-13編集上の変更とスペルの訂正。
2004-02-13新規ドキュメント。

掲載日: 2004-07-13